<template>
  <el-dialog
      :close-on-click-modal="false"
      draggable
      :width="'1500px'"
      align-center
      v-model="aiInfo.visible"
      title="问题自助机器人"
      class="previewDialog"
    >
    流式输出：
      <el-switch
        v-model="isStream"
        inline-prompt
        active-text="是"
        inactive-text="否"
      />
      <div class="chat-container">
        <!-- 聊天主界面 -->
        <ChatPanel
          ref="chatPanelRef"
          :chatList="chatList"
          :outputEnd="outputEnd"
          :aiLoad="aiLoad"
          @send="handleSend"
          @stopOutput="stopOutput"
        />
      </div>
    </el-dialog>
</template>
<script setup >
import {h, nextTick, onMounted, reactive, ref, watchEffect} from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import ChatPanel from './ChatPanel.vue'

// 定义组件名称，避免单词组件名警告
defineOptions({
  name: 'AiDialogComponent'
})

const BASE_URL = 'https://api.deepseek.com'
const API_KEY = 'Bearer sk-6fad1808b96044e2bf2575408d802232'

const isStream = ref(false)
const stopRequested = ref(false) // 添加停止请求标记

const chatList = ref([
  { role: 'system', content: '你是个乐于助人的助手。' },
  { role: 'user', content: '你好!' }
])
const aiLoad = ref(false)
const outputEnd = ref(true) // 是否输出结束
const chatPanelRef = ref(null)

const aiInfo = reactive({
  visible: false
})

const controller = ref(null)

const openDialog = () => {
  aiInfo.visible = true
  createNewChat()
  // let aiData = JSON.parse(sessionStorage.getItem('ai_history'))
  // nextTick(()=>{
  //   chatPanelRef.value?.scrollToBottom()
  // })
  // if(aiData?.length > 0) {
  //   chatList.value = aiData
  //   chatPanelRef.value?.scrollToBottom()
  // }else{
  //   createNewChat()
  // }
}

// 创建新会话
const createNewChat = async () => {
  let data = [
    { role: 'system', content: '你是个乐于助人的助手。' },
    { role: 'user', content: '你好!' }
  ]
  sessionStorage.setItem('ai_history', JSON.stringify(data))
  if(isStream.value){
    await sendMessageStream(data)
  }else{
    await sendMessage(data)
  }
}

// 发送消息
const sendMessage = async (content) => {
  chatPanelRef.value?.scrollToBottom()
  // 输入完成，禁止输入/切换/会话
  outputEnd.value = false
  const result = await fetch(`${BASE_URL}/chat/completions`, {
    method: 'post',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': API_KEY
    },
    signal: controller.value.signal,
    body: JSON.stringify({
      model: "deepseek-reasoner",
      messages: content,
      stream:isStream.value
    })
  })
  chatList.value.push({role: 'assistant', content: '正在思考中...',aiLoad:true})
  chatPanelRef.value?.scrollToBottom()
  await result.json().then(async (res) => {
    outputEnd.value = true
    let {content} = res.choices[0].message
    let idx = chatList.value?.length - 1
    chatList.value[idx].content = content
    chatList.value[idx].aiLoad = false
    sessionStorage.setItem('ai_history', JSON.stringify(chatList.value))
    chatPanelRef.value?.scrollToBottom()
  })
}
// 流式
const sendMessageStream = async (content) => {
  outputEnd.value = false
  const response = await fetch(`${BASE_URL}/chat/completions`, {
    method: 'post',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': API_KEY
    },
    signal: controller.value.signal,
    body: JSON.stringify({
      model: "deepseek-reasoner",
      messages: content,
      stream:isStream.value
    })
  })
  chatList.value.push({role: 'assistant', content: '正在思考中...',aiLoad:true})
  const reader = response.body?.getReader()
  const decoder = new TextDecoder()
  if (!reader) return
  try {
    chatPanelRef.value?.scrollToBottom()
    let content = ''
    while (reader && !stopRequested.value) {
      const { done, value } = await reader.read()
      // done 表示流已经结束 跳出循环
      if (done) break
      // 处理分块数据（示例为按行处理）
      const chunk = decoder.decode(value)
      const lines = chunk.split('\n')
      for (const line of lines) {
        if (line.trim() && !stopRequested.value) {
          // 终止条件判断
          if (line.includes('data: [DONE]')) {
            outputEnd.value = true
            break // 直接退出函数
          }
          // 手动中断函数
          if (stopRequested.value) {
            outputEnd.value = true
            break // 直接退出函数
          }
          const responseText = line.slice(5)
          const jsonData = JSON.parse(responseText).choices[0].delta.content
          content = content + jsonData
          let formattedResponse = formatResponse(content)
          let idx = chatList.value?.length - 1
          chatList.value[idx].content = formattedResponse
          chatList.value[idx].aiLoad = false
          sessionStorage.setItem('ai_history', JSON.stringify(chatList.value))
          // 滚动到底部
          chatPanelRef.value?.scrollToBottom()
        }
      }
    }

  } catch (err) {
    console.error('Stream error:', err)
    // 输出完成，允许输入
    outputEnd.value = true
  } finally {
    // 释放读取器锁，确保资源被正确释放
    outputEnd.value = true
    reader.releaseLock()
  }
}
// 格式化
const formatResponse = (text) => {
  // 确保 text 是字符串类型
  if (text === null || text === undefined) {
    return ''
  }

  // 如果不是字符串，尝试转换为字符串
  if (typeof text !== 'string') {
    try {
      text = String(text)
    } catch (e) {
      console.error('无法将输入转换为字符串:', e)
      return ''
    }
  }

  return text
      .replace(/\[DONE\]/g, '') // 移除[DONE]标记
      .replace(/["""]/g, '') // 移除各种引号
      .replace(/\s+/g, ' ') // 将多个空格替换为单个空格
      .trim() // 修剪首尾空格
}

// 发送
const handleSend = async (content) => {
  if (outputEnd.value) {
    if (content.length < 1) {
      ElMessage.error('请输入')
      return
    }
    chatList.value.push(...content)
    // 发送对话信息
    if(isStream.value){
      await sendMessageStream(content)
    }else{
      await sendMessage(content)
    }
  }
}

// 停止输出
const stopOutput = async () => {
  controller.value.abort()
  createInstance()
  if (!outputEnd.value) {
    outputEnd.value = true
    let idx = chatList.value?.length - 1
    chatList.value[idx].content = isStream.value ? chatList.value[idx].content:'已中断输出！'
    chatList.value[idx].aiLoad = false
    sessionStorage.setItem('ai_history', JSON.stringify(chatList.value))
    ElMessage({
      message: '已停止输出',
      type: 'info',
      duration: 2000
    })
  }
}
// 创建一个 AbortController 实例,用于中断请求
const createInstance = () => {
  controller.value = new AbortController()
}

onMounted(() => {
  createInstance()
})

defineExpose({
  openDialog
})
</script>

<style scoped lang="scss">
.previewDialog {
  .el-dialog__body {
    position: relative;
    padding: 20px !important;
  }

  .el-dialog__header {
    padding: 15px 20px;
    border-bottom: 1px solid #f0f0f0;
  }

  --el-dialog-border-radius: 8px;
}

.chat-container {
  width:100%;
  display: flex;
  height: 700px;
}

/* 添加删除确认弹窗样式 */
:deep(.el-message-box) {
  border-radius: 8px;

  .el-message-box__header {
    padding: 15px 20px;
  }

  .el-message-box__title {
    font-size: 16px;
  }

  .el-message-box__content {
    padding: 20px;
  }

  .el-message-box__btns {
    padding: 10px 20px 15px;
  }
}

/* 添加不喜欢选项的样式 */
:deep(.dislike-dialog) {
  .el-message-box__content {
    padding: 20px;
  }

  .dislike-options {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 10px;
  }

  .dislike-option {
    padding: 10px 15px;
    border-radius: 6px;
    background-color: #f7f7f8;
    cursor: pointer;
    transition: all 0.2s;

    &:hover {
      background-color: #e5f3ee;
      color: #008f5f;
    }
  }
}

</style>
